package com.gateway.api.util;

import com.alibaba.fastjson.JSON;
import lombok.Data;

/**
 * @Description: 调用链记录 后续再搞
 * @author: shaoyu1
 * @date: 2019/11/13 11:23
 */
@Data
public class CallChainContext {

    private String classAndMethod;
    private Object[] params;
    private Object result;
    private CallChainContext next;

    ThreadLocal<CallChainContext> local = new ThreadLocal<>();

    protected static Class<? extends CallChainContext> contextClass = CallChainContext.class;
    protected static final ThreadLocal<? extends CallChainContext> threadLocal = ThreadLocal.withInitial(()-> {
        try {
            return contextClass.newInstance();
        } catch (Throwable e) {
            e.printStackTrace();
            return null;
        }
    });

    public static CallChainContext getContext() {
        return threadLocal.get();
    }

    public CallChainContext(){

    }

    private CallChainContext(String classAndMethod, Object[] params, Object result) {
        this.classAndMethod = classAndMethod;
        this.params = params;
        this.result = result;
    }

    public static ThreadLocal<? extends CallChainContext> addChain(String classAndMethod, Object[]params, Object result) {
        threadLocal.get().getLastChain().setNext(new CallChainContext(classAndMethod,params,result));
        return threadLocal;
    }
    public static CallChainContext getLastChain(){
        CallChainContext callChainContext = threadLocal.get();
        return getLastChain(callChainContext);
    }
    private static CallChainContext getLastChain(CallChainContext callChainContext){
        if(callChainContext.next!=null){
            return getLastChain(callChainContext.next);
        }else
            return callChainContext;
    }

    public static void init(String classAndMethod, Object[]params, Object result){
        CallChainContext callChainContext = threadLocal.get();
        callChainContext.setClassAndMethod(classAndMethod);
        callChainContext.setParams(params);
        callChainContext.setResult(result);
    }
    public static void unset() {
        threadLocal.remove();
    }

    @Override
    public String toString() {
        return generateInfo(this);
    }
    private String generateInfo(CallChainContext context){
        StringBuilder sb = new StringBuilder();
        sb.append("\n\r=>调用方法:"+context.classAndMethod+"[入参:"+ JSON.toJSONString(context.getParams())
                +"],[结果:"+JSON.toJSONString(context.result)+"]");
        if(context.next!=null){
            sb.append(generateInfo(context.next));
        }
        return sb.toString();
    }

}
